package com.gowants.pems.util;

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;  
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;

import org.springframework.web.multipart.MultipartFile;

public class FileTypeJudge {
	/** 
     * Constructor 
     */  
    private FileTypeJudge() {
    }
    
    public static boolean isFile(InputStream inputStream) throws IOException {
        byte[] byteArray = toByteArray(inputStream);
        String str = bytesToHexString(byteArray);
        // 匹配16进制中的 <% ( ) %> 
        // 匹配16进制中的 <? ( ) ?> 
        // 匹配16进制中的 <script | /script> 大小写亦可
        // 通过匹配十六进制代码检测是否存在木马脚本
        String pattern = "(3c25.*?28.*?29.*?253e)|(3c3f.*?28.*?29.*?3f3e)|(3C534352495054)|(2F5343524950543E)|(3C736372697074)|(2F7363726970743E)";
        Pattern mPattern = Pattern.compile(pattern);
        Matcher mMatcher = mPattern.matcher(str);
     
        // 查找相应的字符串
        boolean flag = true;
        if(mMatcher.find()) {
            flag = false;
           //过滤java关键字(java import String print write( read() php request alert system)（暂时先这样解决，这样改动最小，以后想后更好的解决方案再优化）
            String keywordPattern = "(6a617661)|(696d706f7274)|(537472696e67)|(7072696e74)|(777269746528)|(726561642829)|(706870)|(72657175657374)|(616c657274)|(73797374656d)";
            Pattern keywordmPattern = Pattern.compile(keywordPattern);
            Matcher keywordmMatcher = keywordmPattern.matcher(str);
            if(keywordmMatcher.find()){
                flag = false;
            }
        }
        return flag;
   }
    
    private static byte[] toByteArray(InputStream input) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        byte[] buffer = new byte[4096];
        int n = 0;
        while (-1 != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
        }
        return output.toByteArray();
    }
    
    
    public static boolean checkFileFormat(MultipartFile file) {
		if (file == null) {
			return false;
		}
		try {
			String fileName = UploadUtil.getFileName(file);
			String suffix = fileName.substring(fileName.lastIndexOf(".") + 1); 
			String type = FileTypeJudge.getFileType(file.getInputStream());
			if(FileType.TXT.getValue().equals(type)){//TXT,DOCX
				if("TXT".equalsIgnoreCase(suffix)||"DOCX".equalsIgnoreCase(suffix))
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			if(FileType.XLS_DOC.getValue().equals(type)){//PPT,DOC,XLS
				
				if("PPT".equalsIgnoreCase(suffix)||"DOC".equalsIgnoreCase(suffix)||"XLS".equalsIgnoreCase(suffix))
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			if(FileType.XLSX_DOCX.getValue().equals(type)){//XLSX
				if("XLSX".equalsIgnoreCase(suffix))
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			if(FileType.PDF.getValue().equals(type)){//PDF
				if("PDF".equalsIgnoreCase(suffix))
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			if(FileType.PNG.getValue().equals(type)){//PNG
				if("PNG".equalsIgnoreCase(suffix))
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			if(FileType.JPEG.getValue().equals(type)){//JEPG
				if("JPG".equalsIgnoreCase(suffix)||"JEPG".equalsIgnoreCase(suffix))
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			if(FileType.GIF.getValue().equals(type)){//GIF
				if("GIF".equalsIgnoreCase(suffix))
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			if(FileType.TIFF.getValue().equals(type)){//TIFF
				if("TIFF".equalsIgnoreCase(suffix))
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			if(FileType.BMP.getValue().equals(type)){//BMP
				if("BMP".equalsIgnoreCase(suffix))
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			if(FileType.DWG.getValue().equals(type)){//DWG
				if("DWG".equalsIgnoreCase(suffix))
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			
			if(FileType.PSD.getValue().equals(type)){//PSD
				if("PSD".equalsIgnoreCase(suffix))
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			
			if(FileType.RTF.getValue().equals(type)){//RTF
				if("RTF".equalsIgnoreCase(suffix))
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			
			if(FileType.XML.getValue().equals(type)){//XML
				if("XML".equalsIgnoreCase(suffix))
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			if(FileType.JPG.getValue().equals(type)){//JPG
				if("JPG".equalsIgnoreCase(suffix)||"JEPG".equalsIgnoreCase(suffix))
				{
					return true;
				}
				else
				{
					return false;
				}
			}
		}catch (Exception e) {
			//e.printStackTrace();
			return false;
		}
		return false;
	}

    
    
    
    /** 
     * 将文件头转换成16进制字符串 
     * @param 原生byte 
     * @return 16进制字符串 
     */  
    private static String bytesToHexString(byte[] src) {  
        StringBuilder stringBuilder = new StringBuilder();  
        if (src == null || src.length <= 0) {
            return null;
        }  
        for (int i = 0; i < src.length; i++) {  
            int v = src[i] & 0xFF;  
            String hv = Integer.toHexString(v);  
            if (hv.length() < 2) {  
                stringBuilder.append(0);  
            }  
            stringBuilder.append(hv);  
        }  
        return stringBuilder.toString();  
    }  
  
    /** 
     * 得到文件头 
     * @param filePath 文件路径 
     * @return 文件头 
     * @throws IOException 
     */  
    private static String getFileContent(InputStream is) throws IOException {  
        byte[] b = new byte[28];
        InputStream inputStream = null;  
        try {  
            is.read(b, 0, 28);
        } catch (IOException e) {  
            e.printStackTrace();  
            throw e;  
        } finally {  
            if (inputStream != null) {  
                try {  
                    inputStream.close();  
                } catch (IOException e) {  
                    e.printStackTrace();
                    throw e;  
                }  
            }  
        }  
        return bytesToHexString(b);
    }  
  
    /** 
     * 获取文件类型类
     * @param filePath 文件路径 
     * @return 文件类型 
     */  
    public static FileType getType(InputStream is) throws IOException {  
        String fileHead = getFileContent(is);
        if (fileHead == null || fileHead.length() == 0) {  
            return null;  
        }  
        fileHead = fileHead.toUpperCase();  
        FileType[] fileTypes = FileType.values();  
        for (FileType type : fileTypes) {  
            if (fileHead.startsWith(type.getValue())) {  
                return type;  
            }
        }  
        return null;  
    }
  
    /**
     * 获取文件类型
     * @param is
     * @return
     * @throws Exception
     */
    public static String getFileType(InputStream is) throws Exception{
    	FileType fileType = getType(is);
    	if(fileType!=null){
    		return fileType.getValue();    		
    	}
    	return null;
    }
    
    
    public static void resize1(InputStream stream, String path) throws Exception  {
        if (stream == null) {
            return;
        }
        BufferedImage src = ImageIO.read(stream);
        int old_w = src.getWidth();
        // 得到源图宽
        int old_h = src.getHeight();
        // 得到源图长
        BufferedImage newImg = null;
        // 判断输入图片的类型
        switch (src.getType()) {
        case 13:
          // png,gif
          newImg = new BufferedImage(old_w, old_h, BufferedImage.TYPE_4BYTE_ABGR);
          break;
        default:
          newImg = new BufferedImage(old_w, old_h, BufferedImage.TYPE_INT_RGB);
          break;
        }
        Graphics2D g = newImg.createGraphics();
        // 从原图上取颜色绘制新图
        g.drawImage(src, 0, 0, old_w, old_h, null);
        g.dispose();
        // 根据图片尺寸压缩比得到新图的尺寸
        newImg.getGraphics().drawImage(
        src.getScaledInstance(old_w, old_h, Image.SCALE_SMOOTH), 0,0, null);
        
        stream.close();
        //ImageIO.write(newImg, endName, newFile);
        
  }

}
